package com.ruoyi.ai.service;

import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.ResultCallback;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.JsonUtils;
import io.reactivex.Flowable;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.concurrent.Semaphore;


/**
 * 灵积大模型实现
 * @author coach tam
 * @email 327395128@qq.com
 * @create 2024/05/13
 * @since 1.0.0
 * 〈坚持灵活 灵活坚持〉
 */
@Component
@Slf4j
public class LingJiLargeModel implements LargeModelService {
    private static final Logger logger = LoggerFactory.getLogger(LingJiLargeModel.class);
    public static final String API_KEY = "sk-HEm8zrNT7o";

    private static void handleGenerationResult(GenerationResult message, StringBuilder fullContent) {
        fullContent.append(message.getOutput().getChoices().get(0).getMessage().getContent());
        logger.info("Received message: {}", JsonUtils.toJson(message));
    }
    private static GenerationParam buildGenerationParam(Message userMsg) {
        return GenerationParam.builder()
                .model("qwen-turbo")
                .messages(Arrays.asList(userMsg))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .topP(0.8)
                .apiKey(API_KEY)
                .incrementalOutput(true)
                .build();
    }

    public static void streamCallWithMessage(Generation gen, Message userMsg)
            throws NoApiKeyException, ApiException, InputRequiredException {
        GenerationParam param = buildGenerationParam(userMsg);
        Flowable<GenerationResult> result = gen.streamCall(param);
        StringBuilder fullContent = new StringBuilder();

        result.blockingForEach(message -> handleGenerationResult(message, fullContent));

        logger.info("Full content: \n{}", fullContent.toString());
    }

    public static void streamCallWithCallback(Generation gen, Message userMsg)
            throws NoApiKeyException, ApiException, InputRequiredException, InterruptedException {
        GenerationParam param = buildGenerationParam(userMsg);
        Semaphore semaphore = new Semaphore(0);
        StringBuilder fullContent = new StringBuilder();

        gen.streamCall(param, new ResultCallback<GenerationResult>() {
            @Override
            public void onEvent(GenerationResult message) {
                handleGenerationResult(message, fullContent);
            }

            @Override
            public void onError(Exception err) {
                logger.error("Exception occurred: {}", err.getMessage());
                semaphore.release();
            }

            @Override
            public void onComplete() {
                logger.info("Completed");
                semaphore.release();
            }
        });

        semaphore.acquire();
        logger.info("Full content: \n{}", fullContent);
    }
    @Override
    public Flowable<GenerationResult> streamCheckAnswer(String question, String answer) {
        Flowable<GenerationResult> result;
        try {
            String prompt = "请评估以下面试题的回答情况，给出评分，评分规则是0至10分的评分，0为非常差，10为满分。问题是:"+question+"  答案是:"+answer+"。整体返回的文本内容只能包含建议和评分，整体返回的文本格式为: 建议:xxx; \n  评分:x分。";
            Generation gen = new Generation();
            Message userMsg = Message.builder().role(Role.USER.getValue()).content(prompt).build();
            result = gen.streamCall(buildGenerationParam(userMsg));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }


    public static void main(String[] args) {
        try {
            String question = "java基本数据类型";
            String answer = "byte int short long char boolean float double";
//            String answer = "byte: 8位，有符号，范围为-128到127\n" +
//                    "short: 16位，有符号，范围为-32768到32767\n" +
//                    "int: 32位，有符号，范围为-2^31到2^31-1\n" +
//                    "long: 64位，有符号，范围为-2^63到2^63-1";
            String prompt = "请评估以下面试题的回答情况，给出评分，评分规则是0至10分的评分，0为非常差，10为满分。问题是:"+question+"  答案是:"+answer+"。整体返回的文本内容只能包含建议和评分，整体返回的文本格式为: 建议:x;   评分:x分。";
//            String prompt = "请评估以下面试题的回答情况，给出0至10分的评分，0为非常差，10为满分，并给出其他评价和建议。将评价和建议按照标准json格式{\"建议\": \"xx\", \"评分\": 0}返回。问题是:java基本数据类型  答案是:int long byte char";
            Generation gen = new Generation();
            Message userMsg = Message.builder().role(Role.USER.getValue()).content(prompt).build();

//            streamCallWithMessage(gen, userMsg);
            streamCallWithCallback(gen, userMsg);
        } catch (ApiException | NoApiKeyException | InputRequiredException | InterruptedException e) {
            log.error("An exception occurred: {}", e.getMessage());
        }
    }
}
